package com.wx.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author sunsu
 * 
 */
public class HttpUtil<T> {
	private static Logger log = LoggerFactory.getLogger(HttpUtil.class);
	public static void main(String[] args) throws IOException {
		String requestUrl = Constants.GET_ACCESSTOKEN_URL.replace("APPID",
				Constants.APPID).replace("APPSECRET", Constants.SECRET);
		
		String params = "12341";
		HttpUtil http = new HttpUtil<Map>();
		String res = post(requestUrl,new HashMap());
		System.out.println(res);

	}

	/**
	 * 发送 get请求访问
	 * 
	 * @param url
	 * @return
	 */
	public static String get(String url) {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet(url);
		String responseContent = "";
		try {
			CloseableHttpResponse response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return responseContent;
	}

	/**
	 * 发送 post请求访问，并根据传递参数不同返回不同结果
	 */
	public static<T> String post(String url, T params) {
		String responseContent = "";
		// 创建默认的httpClient实例.
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 创建httppost
		HttpPost httppost = new HttpPost(url);
		try {
			if(params.getClass() == String.class){ //提交Json字符串
				log.debug("submit type: JSON");
				// 创建参数队列
				StringEntity param = new StringEntity((String) params,ContentType.APPLICATION_JSON);
				httppost.setEntity(param);
			}else if(params.getClass() == Map.class){ 
				log.debug("submit type: Map");
				Map p = (Map)params;
				// 创建参数队列
				List<NameValuePair> formparams = new ArrayList<NameValuePair>();
				// 遍历参数，封装参数队列
				Set<String> keys = p.keySet();
				Iterator<String> it = keys.iterator();
				while (it.hasNext()) {
					String key = it.next();
					String value = (String) p.get(key);
					formparams.add(new BasicNameValuePair(key, value));
				}
				UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
				httppost.setEntity(uefEntity);
			}

			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					responseContent = EntityUtils.toString(entity, "UTF-8");
				}
			} finally {
				response.close();
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	/**
	 * 发送 get请求下载文件
	 * 
	 * @param url
	 * @param file
	 *            下载文件保存的名称
	 * @return
	 */
	public static String dowload(String url, String path) {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet(url);
		String filename = "";
		try {
			CloseableHttpResponse response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();

			//获取下载文件名
			Header contentHeader = response
					.getFirstHeader("Content-disposition");
			if (contentHeader != null) {
				HeaderElement[] values = contentHeader.getElements();
				if (values.length == 1) {
					NameValuePair param = values[0]
							.getParameterByName("filename");
					if (param != null) {
						filename = param.getValue();
					}
				}
			}

			//判断请求是否流数据
			if (entity.isStreaming()) {
				filename = path + filename;
				File img = new File(filename);
				FileOutputStream fos = new FileOutputStream(img);
				entity.writeTo(fos);
				fos.close();
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return filename;
	}


	/**
	 * post上传文件
	 * 
	 * @param url
	 * @param file 上传的文件
	 * @param params 上传提交参数键值对
	 * @return
	 * @throws Exception
	 */
	public static String upload(String url, String file,Map<String, String> params) throws Exception {

		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);

			FileBody bin = new FileBody(new File(file));
			MultipartEntityBuilder builder = MultipartEntityBuilder.create().addPart("media", bin);

			if(params != null && !params.isEmpty()){
				// 遍历参数，封装参数队列
				Set<String> keys = params.keySet();
				Iterator<String> it = keys.iterator();
				while (it.hasNext()) {
					String key = it.next();
					String value = params.get(key);
					builder.addPart(key, new StringBody(value,Charset.forName("UTF-8")));
				}
			}
			HttpEntity reqEntity = builder.build();
			httppost.setEntity(reqEntity); 
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					System.out.println("Response content length: "
							+ resEntity.getContentLength());
				}
				return EntityUtils.toString(resEntity, "UTF-8");
			} finally {
				response.close();
			}
		} finally {
			httpclient.close();
		}
	}

	/**
	 * 下载文件
	 * 
	 * @param url
	 *            网络文件路径
	 * @param localpath
	 *            保存本地路径
	 * @return 文件名
	 */
	/*
	 * public static String downFile(String url,String localpath) { String
	 * uploadfilename = ""; InputStream is = null; OutputStream os = null; try {
	 * is = downFileStream(url); String filename =
	 * url.substring(url.lastIndexOf("/"), url.length()); File file = new
	 * File(localpath); if (!file.exists()) { file.mkdirs(); } os = new
	 * FileOutputStream(file + filename); byte[] b = new byte[1024]; int ch = 0;
	 * while ((ch = is.read(b)) != -1) { os.write(b,0,ch); } os.flush(); } catch
	 * (Exception e) { e.printStackTrace(); } finally { if (os != null) try {
	 * os.close(); } catch (IOException e) { e.printStackTrace(); } } return
	 * uploadfilename; }
	 */

	/**
	 * 获取下载输入流
	 * 
	 * @param url
	 *            网络文件路径
	 * @return
	 */
	/*
	 * public static InputStream downFileStream(String url) { InputStream is =
	 * null; try { HttpClient httpClient = new HttpClient(); PostMethod post =
	 * new PostMethod(url);
	 * 
	 * post.getParams().setParameter( HttpMethodParams.HTTP_CONTENT_CHARSET,
	 * "UTF-8"); int stauts = httpClient.executeMethod(post); if (stauts ==
	 * HttpStatus.SC_OK) { is = post.getResponseBodyAsStream(); } } catch
	 * (Exception e) { e.printStackTrace(); } finally { } return is; }
	 */

	/**
	 * 上传文件
	 * 
	 * @param url
	 *            网络文件路径
	 * @param is
	 *            上传文件输入流
	 * @return
	 */
	/*
	 * public static boolean uploadFile(String url, InputStream is) { try {
	 * HttpClient httpClient = new HttpClient(); PostMethod post = new
	 * PostMethod(url);
	 * 
	 * httpClient.getParams().setContentCharset("UTF-8");
	 * post.setRequestEntity(new
	 * InputStreamRequestEntity(is,"multipart/form-data")); int status =
	 * httpClient.executeMethod(post); if (status == HttpStatus.SC_OK) { return
	 * true; } } catch (Exception e) { e.printStackTrace(); } return false; }
	 */

}
